package modele;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;

import codebase.IOrdre;
import codebase.IPartie;

public abstract class Ordre extends UnicastRemoteObject implements Serializable, IOrdre {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Puissance commanditaire;
	private String typeUnite;
	private Region regOrigine;
	private Region regDestination;
	private int force;
	private boolean croisement;
	private ArrayList<Ordre> listeConvoi;

	public Ordre(Puissance iPuissance, String typeUnite, Region regOr, Region regDes)
			throws RemoteException {
		this.typeUnite = typeUnite;
		this.commanditaire = iPuissance;
		this.regOrigine = regOr;
		this.regDestination = regDes;
		this.force = 1;
		this.croisement = false;
		this.listeConvoi = new ArrayList<Ordre>();
	}

	public abstract String getTypeOrdre();

	public abstract boolean verifValidite();

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Ordre other = (Ordre) obj;
		if (commanditaire == null) {
			if (other.commanditaire != null)
				return false;
		} else if (!commanditaire.equals(other.commanditaire))
			return false;
		if (regDestination == null) {
			if (other.regDestination != null)
				return false;
		} else if (!regDestination.equals(other.regDestination))
			return false;
		if (regOrigine == null) {
			if (other.regOrigine != null)
				return false;
		} else if (!regOrigine.equals(other.regOrigine))
			return false;
		if (typeUnite == null) {
			if (other.typeUnite != null)
				return false;
		} else if (!typeUnite.equals(other.typeUnite))
			return false;
		return true;
	}

	public Puissance getCommanditaire() {
		return commanditaire;
	}

	public String getTypeUnite() {
		return typeUnite;
	}

	public void setCommanditaire(Puissance commanditaire) {
		this.commanditaire = commanditaire;
	}

	public Region getRegOrigine() {
		return regOrigine;
	}

	public void setRegOrigine(Region regOrigine) {
		this.regOrigine = regOrigine;
	}

	public Region getRegDestination() {
		return regDestination;
	}

	public void setRegDestination(Region regDestination) {
		this.regDestination = regDestination;
	}

	public int getForce() {
		return force;
	}

	public void incrementeForce() {
		this.force++;
	}

	public boolean isCroisement() {
		return croisement;
	}

	public void setCroisement(boolean croisement) {
		this.croisement = croisement;
	}

	public void addConvoi(Ordre o) {
		this.listeConvoi.add(o);
	}

	public static Ordre verifSyntaxe(String s) {
		String typeU = "'Erreur Class-Ordre:46'";
		Puissance donneurOrdre = null;
		Region regOr, regDes;
		Ordre o = null;

		// _______________________0__1__2__3__4__5__6
		// Tenir position GB A BOU T
		// Attaquer FR A PAR - PIC
		// Soutenir offensivement FR F MAN S PAR - PIC
		// Soutenir defensivement GB A BEL S PIC
		// Convoi FR F MED C NAF - NAP
		// _______________________0__1__2__3__4__5__6

		String[] tabString = s.split(" ");
		try {
			// Verification que la region de Depart existe
			if (!IPartie.carte.regionExist(tabString[2])) {
				return null;
			}
			regOr = IPartie.carte.getRegion(tabString[2]);

			/*
			 * Verification qu'il y a bien une unite sur la region et quelle
			 * soit de bon type et que celle-ci appartient bien a la puissance
			 * ////TODO A rajouter quand Puissance ok
			 */
			typeU = tabString[1];
			donneurOrdre = regOr.getOccupant().getProprietaire();
			/*
			 * if (regOr.getOccupant().getTypeUniteAbr() == tabString[1] &&
			 * regOr.getOccupant().getProprietaire().getAbreviation()
			 * .equalsIgnoreCase(tabString[0])) { typeU = tabString[1];
			 * donneurOrdre = regOr.getOccupant().getProprietaire(); } else {
			 * return null; }
			 */

			// Verification du type Ordre
			if (tabString[3].equalsIgnoreCase("T") || tabString[3].equalsIgnoreCase("X")) {
				o = new Defense(donneurOrdre, typeU, regOr);
			} else if (tabString[3].equalsIgnoreCase("-")) { // Attaque
				// Verif regionDest existe
				if (!IPartie.carte.regionExist(tabString[4])) {
					return null;
				}
				regDes = IPartie.carte.getRegion(tabString[4]);
				o = new Attaque(donneurOrdre, typeU, regOr, regDes);
			} else if ((tabString[3].equalsIgnoreCase("S"))) { // Soutient
				// region soutenu existe
				if (!IPartie.carte.regionExist(tabString[4])) {
					return null;
				}
				if (tabString.length == 6) { // Soutient offensif
					// Si la region soutenu existe et que c'est bien un ordre
					// d'attaque soutenue
					if (!IPartie.carte.regionExist(tabString[6])
							|| !tabString[5].equalsIgnoreCase("-")) {
						return null;
					}
					o = new SoutienOffensif(donneurOrdre, typeU, regOr,
							IPartie.carte.getRegion(tabString[4]),
							IPartie.carte.getRegion(tabString[6]));
				} else { // Soutient defensif
					o = new SoutienDefensif(donneurOrdre, typeU, regOr,
							IPartie.carte.getRegion(tabString[4]));
				}
			} else if (tabString[3].equalsIgnoreCase("C") && tabString.length == 7) {
				/*
				 * //Le type est bien un flotte //TODO A rajouter quand
				 * puissance ok if(!typeU.equalsIgnoreCase("F")){ return null; }
				 */
				// region convoyée existe
				if (!IPartie.carte.regionExist(tabString[4])) {
					return null;
				}
				// region convoye existe et bien ordre d'attauqe
				if (!IPartie.carte.regionExist(tabString[6]) || !tabString[5].equalsIgnoreCase("-")) {
					return null;
				}
				o = new Convoi(donneurOrdre, typeU, regOr, IPartie.carte.getRegion(tabString[4]),
						IPartie.carte.getRegion(tabString[6]));
				// TODO a tester et rajouter ds diamgrame de classe pour convoi
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		return o;
	}
}
